#include "udt.h"
#include "udt_priv.h"

using namespace std;

static ud_set s_rdset;
static ud_set s_wrset;

void udtp_startup(void)
{
	UDT::startup();
}

void udtp_cleanup(void)
{
	UDT::cleanup();
}

int udtp_get_sock_by_udt(UDTSOCKET u)
{
	return UDT::get_sock_by_usock(u);
}

int udtp_geterrocode(void)
{
	return UDT::getlasterror().getErrorCode();
}

const char *udtp_geterromessage(void)
{
	return UDT::getlasterror().getErrorMessage();
}

int udtp_socket(int af, int type, int protocol)
{
	return UDT::socket(af, type, protocol);
}

int udtp_getsockopt(UDTSOCKET u, int level,
		SOCKOPT optname, char* optval, int* optlen)
{
	return UDT::getsockopt(u, level, optname, optval, optlen);
}

int udtp_setsockopt(UDTSOCKET u, int level,
		SOCKOPT optname, const char* optval, int optlen)
{
	return UDT::setsockopt(u, level, optname, optval, optlen);
}

UDTSOCKET udtp_accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen)
{
	return UDT::accept(u, addr, addrlen);
}

int udtp_bind(UDTSOCKET u, struct sockaddr* name, int namelen)
{
	return UDT::bind(u, name, namelen);
}

int udtp_close(UDTSOCKET u)
{
	return UDT::close(u);
}

void udtp_udclr(int fd, int rdflag)
{
	if (rdflag)
		s_rdset.erase(fd);
	else
		s_wrset.erase(fd);
}

int udtp_udisset(int fd, int rdflag)
{
	if (rdflag)
		return (s_rdset.find(fd) != s_rdset.end());
	else
		return (s_wrset.find(fd) != s_wrset.end());
}

void udtp_udset(int fd, int rdflag)
{
	if (rdflag)
		s_rdset.insert(fd);
	else
		s_wrset.insert(fd);
}

void udtp_udzero(int rdflag)
{
	if (rdflag)
		s_rdset.clear();
	else
		s_wrset.clear();
}
int udtp_connect(UDTSOCKET u, const struct sockaddr* name, int namelen)
{
	return UDT::connect(u, name, namelen);
}

int udtp_getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen)
{
	return UDT::getpeername(u, name, namelen);
}

int udtp_getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen)
{
	return UDT::getsockname(u, name, namelen);
}

int udtp_listen(UDTSOCKET u, int backlog)
{
	return UDT::listen(u, backlog);
}

int udtp_perfmon(UDTSOCKET u, TRACEINFO* perf, int clear)
{
	return UDT::perfmon(u, perf, clear);
}

int udtp_recv(UDTSOCKET u, char* buf, int len, int flags)
{
	return UDT::recv(u, buf, len, flags);
}

//int64_t udtp_recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset,int64_t size, int block = 366000);
int udtp_recvmsg(UDTSOCKET u, char* msg, int len)
{
	return UDT::recvmsg(u, msg, len);
}

int udtp_select(int nfds, int rdflag, int wrflag,
		const struct timeval* timeout)
{
#if 0
	ud_set readfds;
	ud_set writefds;
	ud_set *rdfds;
	ud_set *wrfds;
	if (rdflag) {
		readfds = s_rdset;
		rdfds = &readfds;
	}
	else
		rdfds = NULL;
	if (wrflag) {
		writefds = s_wrset;
		wrfds = &writefds;
	}
	else
		wrfds = NULL;
	return UDT::select(nfds, rdfds, wrfds, NULL, timeout);
#else
	ud_set *rdfds;
	ud_set *wrfds;
	rdfds = rdflag ? &s_rdset : NULL;
	wrfds = wrflag ? &s_wrset : NULL;
	return UDT::select(nfds, rdfds, wrfds, NULL, timeout); 
#endif
}

int udtp_send(UDTSOCKET u, const char* buf, int len, int flags)
{
	return UDT::send(u, buf, len, flags);
}

int udtp_sendmsg(UDTSOCKET u, const char* msg, int len, int ttl, int inorder)
{
	return UDT::sendmsg(u, msg, len, ttl, inorder);
}

